package com.way.designpatterncodepratice.singleton;

/**
 * @author liangliwei 80551025
 * @description
 * @date 2020-06-22
 */
public class LazySingletonDoubleCheck {
    /**
     * volatile 保证可见性但是不保证原子性 如i++ 与 防止指令重排
     */
    private static volatile LazySingletonDoubleCheck lazySingletonUnsafe;


    /**
     * 私有化构造器
     */
    private LazySingletonDoubleCheck() {
        System.out.println("LazySingletonUnsafe构造器");
    }

    /**
     * 公有的静态获取实例方法 线程安全 但是效率低 因为每个通过getInstance() 获取的都要进入synchronized同步
     */
    public static LazySingletonDoubleCheck getInstance(){
        if(lazySingletonUnsafe==null){
            /**
             * 假如多个线程进入这里 如果 线程1 线程2 线程3
             */
            synchronized(LazySingletonDoubleCheck.class){
                /**
                 * 这里只有一个线程进入 假如 线程2进入了
                 * 因为有if判断 第一次还没创建实例的时候  线程2new了实例
                 * 后面 线程1 线程3 进来了但是有这个if判断 所以不会再new 新的实例
                 * 因为线程2已经 new了实例  所以后面其他线程 就会正常在第一个if判断被拦截 不会进入synchronized 同步块
                 */
                if(lazySingletonUnsafe==null) {
                    lazySingletonUnsafe = new LazySingletonDoubleCheck();
                }
            }

        }
        return lazySingletonUnsafe;
    }
}
